/**
 * Copyright (c) 2006-2012 Las Venturas Playground, LVP Mineground
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.mineground.protect;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityBreakDoorEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractEvent;

public class EventListener implements Listener {
    private FocusTracker mFocusTracker;
    
    public EventListener(FocusTracker focusTracker) {
        mFocusTracker = focusTracker;
    }
    
    /**
     * Should a given block be processed? This should be false in case the plugin is disabled, or
     * the block isn't protectable, or the block itself is not in a protected state.
     */
    private boolean shouldProcessBlock(Block block) {
        if (Plugin.isPluginEnabled() == false || block == null)
            return false;
        
        Material blockMaterial = block.getType();
        if (blockMaterial != Material.CHEST &&
            blockMaterial != Material.WOOD_DOOR &&
            blockMaterial != Material.IRON_DOOR &&
            blockMaterial != Material.FURNACE &&
            blockMaterial != Material.DISPENSER) {
            return false;
        }
        
        return true;
    }
    
    private ProtectedBlock findProtectionForBlock(Block block) {
        // TODO: Do player/location matching and find the block.
        return null;
    }
    
    private ProtectedBlock checkShouldProcessAndFindProtectionForBlock(Block block) {
        if (!shouldProcessBlock(block))
            return null;
        
        return findProtectionForBlock(block);
    }
    
    /**
     * Consider implementing the following methods if they prove to be useful. I chose to leave them
     * out in the initial implementation as I'm not convinced by their benefit.
     * 
     * @todo Consider implementing onPlayerDropItem (usage unknown).
     * @todo Consider implementing onPlayerChat (catch mistyped commands).
     * @todo Consider implementing onPlayerQuit (for online player tracking).
     * @todo Consider implementing onBlockRedstoneChange (usage unknown).
     * @todo Consider implementing onSignChange (usage unknown).
     */
    
    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.isCancelled())
            return;
        
        if (event.getAction() != Action.LEFT_CLICK_BLOCK &&
            event.getAction() != Action.RIGHT_CLICK_BLOCK)
            return;
        
        Block block = event.getClickedBlock();
        Player player = event.getPlayer();
        
        if (shouldProcessBlock(block) == false)
            return;
        
        Block previousFocus = mFocusTracker.updateAndReturnPreviousValue(player, block);
        
        ProtectedBlock protection = findProtectionForBlock(block);
        if (protection == null) {
            if (previousFocus == block)
                return;
            
            player.sendMessage("This " + block.getType().name().toLowerCase() + " has not been protected. Type:");
            player.sendMessage("\u00A7f/cprivate \u00A73Protect this object so only you can use it.");
            player.sendMessage("\u00A7f/cpassword \u00A7b<Password> \u00A73Protect this object based on a password.");
            return;
        }
        
        if (protection.canBeAccessedByPlayer(player) == false)
            event.setCancelled(true);
    }
    
    @EventHandler
    public void onEntityBreakDoor(EntityBreakDoorEvent event) {
        /**
         * @todo Implement. Used when an entity breaks a door.
         */
    }
    
    @EventHandler
    public void onEntityExplode(EntityExplodeEvent event) {
        /**
         * @todo Implement. Used when an entity explodes, i.e. a creeper.
         * @todo Figure out what this creeper heal stuff is.
         */
    }
    
    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        /**
         * @todo Implement. Used when a block breaks for whatever reason (by a player?).
         * @note Keep double chests in mind.
         */
    }
    
    @EventHandler
    public void onBlockPistonRetract(BlockPistonRetractEvent event) {
        /**
         * @todo Implement. Used when a piston retracts.
         */
    }
    
    @EventHandler
    public void onBlockPistonExtend(BlockPistonExtendEvent event) {
        /**
         * @todo Implement. Used when a piston extends.
         */
    }
    
    @EventHandler
    public void onBlockPlace(BlockPlaceEvent event) {
        /**
         * @todo Implement. Used when a block is being placed.
         */
    }
}
